library(tidyverse)
library(httr)
library(sf)
library(ggplot2)
library(tmap)
library(plotly)
library(glue)
Define common columns
cols <- c(
"Date",
"Regio",
"Period",
"Population",
"Deaths",
"MortalityRate")
Load historical data for flu dataset
cols.historic <-
c(
cols,
"Year"
)
data.historic <- read_rds("../results/data.Rds") %>% rename(Regio = RegioS) %>% select(cols.historic)
# data.flu2018 <- data.historic %>%
# filter(Year == 2018 | Year == 2017) %>%
# group_by(Year) %>%
# mutate(
# LastPeriod = max(Period, na.rm = T),
# Period = if_else(Year == 2017 & Period == LastPeriod, 0, Period),
# ) %>%
# ungroup() %>%
# mutate(Year = if_else(Period == 0, 2018, Year)) %>%
# filter(Year == 2018) %>%
# rename(Flu2018 = MortalityRate)
Additional RIVM data
data.rivm <- read_rds("../results/rivm.Rds") %>% rename(Rivm = Deaths)
Data for 2020 corona crisis
cols.corona <-
c(
cols,
"ExpectedMortality", "AvgMortality", "UnexpectedMortality", "ExcessiveMortality", "Flu2018"
)
data.corona <- read_rds("../results/data.corona.Rds") %>% rename(Regio = RegioS) %>% select(cols.corona) %>%
full_join(data.rivm, by = c("Regio", "Date", "Period")) %>%
drop_na(Date)
data.corona %>% filter(Regio == "NL") %>% arrange(Date)
Geographical entities
areas <- GET("https://opendata.arcgis.com/datasets/e1f0dd70abcb4fceabbc43412e43ad4b_0.geojson") %>% content(as = "text") %>%
read_sf() %>%
rename(RegioS = Gemeentecode) %>%
arrange(Gemeentenaam)
No encoding supplied: defaulting to UTF-8.
write_rds(areas, "../results/plots/areas.Rds")
Create a timeline and add splines for smooth charts
# Do some interpolation
dates <- data.corona %>% drop_na("Period", "Date") %>% distinct(Date) %>% pull("Date")
fields <- c("MortalityRate", "ExpectedMortality", "AvgMortality", "Flu2018", "DeathsUnexpected", "DeathsAboveAvg", "Rivm", "Deaths")
days <- data.frame(Date = seq(min(dates), to = max(dates), by = "days")) %>%
crossing(data.corona %>% select(Regio) %>% distinct()) %>%
crossing(fields) %>%
set_names(c("Date", "Regio", "Variable"))
data.mort <- data.corona %>%
mutate(
DeathsUnexpected = UnexpectedMortality * Population / 100000,
DeathsAboveAvg = ExcessiveMortality * Population / 100000,
) %>%
gather("Variable", "Value", fields) %>%
drop_na(Regio, Variable, Date) %>%
full_join(days) %>%
group_by(Regio, Variable) %>%
filter(sum(!is.na(Value)) > 0) %>%
# summarise(n = n()) %>% arrange(n)
mutate(
Interpolated = approx(Date, Value, xout=Date)$y,
Absolute = if_else(Variable == "MortalityRate", Value * Population / 100000, as.double(NA))
) %>%
ungroup() %>%
select("Regio", "Date", "Period", "Variable", "Value", "Interpolated", "Absolute")
Joining, by = c("Date", "Regio", "Variable")
data.mort %>% filter(Regio == "NL") %>% arrange(Date)
write_rds(data.mort, "../results/plots/mortovertime.Rds")
Example 1
x <- data.mort %>%
filter(Variable %in% c("MortalityRate", "ExpectedMortality", "AvgMortality", "Flu2018")) %>%
filter(Regio == "GM0345")
tooltip <- ("<b>{Date}</b>
Mortality rate: {floor(Value)}
Deaths: {floor(Absolute)}"
)
ggplotly(tooltip = "text", ggplot(
x,
aes(
group = Variable,
color = Variable,
text = tooltip %>% glue()
)
) +
geom_point(aes(x = Date, y = Value)) +
geom_line(aes(x = Date, y = Interpolated)) +
labs(x = "Period (weeks)" %>% glue(), y = "Deaths by 100.000 inhabitants") +
theme_minimal() +
theme(legend.title = element_blank())
)
Example 2
x <- data.mort %>%
filter(Variable %in% c("Rivm", "DeathsAboveAvg", "DeathsUnexpected")) %>%
filter(Regio == "NL")
tooltip <- ("<b>{Date}</b>
Deaths: {floor(Interpolated)}")
ggplotly(ggplot(
x,
aes(
group = Variable,
color = Variable,
text = tooltip %>% glue()
)
) +
geom_line(aes(x = Date, y = Interpolated)) +
geom_point(aes(x = Date, y = Value)) +
labs(x = "Period (weeks)" %>% glue(), y = "Absolute deaths") +
theme_minimal() +
theme(legend.title = element_blank()) +
scale_color_brewer(palette = "Set2"),
tooltip = "text"
)
Spatial dataset
data.spatial_absolute <- areas %>% left_join(data.corona, by = c("RegioS" = "Regio")) %>%
mutate(
ActualMortality = round(MortalityRate * Population / 100000),
ExpectedMortality = round(ExpectedMortality * Population / 100000),
AvgMortality = round(AvgMortality * Population / 100000),
UnexpectedMortality = round(UnexpectedMortality * Population / 100000),
ExcessiveMortality = round(ExcessiveMortality * Population / 100000),
)
write_rds(data.spatial_absolute, "../results/plots/spatial_absolute.Rds")
Example
tm_shape(data.spatial_absolute %>% filter(Period == 4)) +
tm_polygons(
col = "MortalityRate",
id = "Gemeentenaam",
title = "Mortality rate by municipality"
)

Summary table
year_high_mort <- data.historic %>% group_by(Regio, Year) %>%
summarise(MortalityRate = mean(MortalityRate)) %>%
arrange(desc(MortalityRate)) %>%
slice(1) %>% arrange(Regio) %>% ungroup() %>%
select(YearHighestMort = Year, Regio)
data.summary <- data.mort %>%
filter(Period > 0 & Variable %in% c("Deaths", "Rivm", "DeathsAboveAvg", "DeathsUnexpected")) %>%
group_by(Regio, Variable) %>%
summarise(Value = floor(sum(Value, na.rm = T))) %>%
spread(Variable, Value) %>%
ungroup() %>%
left_join(year_high_mort)
Joining, by = "Regio"
write_rds(data.summary, "../results/plots/summary.Rds")
data.mort %>%
filter(Regio == "GM0345" & Variable %in% c("Rivm")) %>% arrange(Date) %>%
group_by(Regio, Variable) %>% summarise(Value = sum(Value, na.rm = T)) %>% spread(Variable, Value)
data.summary %>% filter(Regio == "GM0345")
LS0tDQp0aXRsZTogIlByZXByb2Nlc3MgZGF0YSBmb3IgcGxvdHRpbmcgaW4gdGhlIGRhc2hib2FyZCINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGh0dHIpDQpsaWJyYXJ5KHNmKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeSh0bWFwKQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KGdsdWUpDQpgYGANCg0KIyMjIERlZmluZSBjb21tb24gY29sdW1ucw0KDQpgYGB7cn0NCmNvbHMgPC0gYygNCiAgIkRhdGUiLA0KICAiUmVnaW8iLA0KICAiUGVyaW9kIiwNCiAgIlBvcHVsYXRpb24iLA0KICAiRGVhdGhzIiwNCiAgIk1vcnRhbGl0eVJhdGUiKQ0KYGBgDQoNCiMjIyBMb2FkIGhpc3RvcmljYWwgZGF0YSBmb3IgZmx1IGRhdGFzZXQNCg0KYGBge3J9DQpjb2xzLmhpc3RvcmljIDwtDQogIGMoDQogICAgY29scywNCiAgICAiWWVhciINCiAgKQ0KDQpkYXRhLmhpc3RvcmljIDwtIHJlYWRfcmRzKCIuLi9yZXN1bHRzL2RhdGEuUmRzIikgJT4lIHJlbmFtZShSZWdpbyA9IFJlZ2lvUykgJT4lIHNlbGVjdChjb2xzLmhpc3RvcmljKQ0KDQojIGRhdGEuZmx1MjAxOCA8LSBkYXRhLmhpc3RvcmljICU+JSANCiMgICBmaWx0ZXIoWWVhciA9PSAyMDE4IHwgWWVhciA9PSAyMDE3KSAlPiUgDQojICAgZ3JvdXBfYnkoWWVhcikgJT4lDQojICAgbXV0YXRlKA0KIyAgICAgTGFzdFBlcmlvZCA9IG1heChQZXJpb2QsIG5hLnJtID0gVCksDQojICAgICBQZXJpb2QgPSBpZl9lbHNlKFllYXIgPT0gMjAxNyAmIFBlcmlvZCA9PSBMYXN0UGVyaW9kLCAwLCBQZXJpb2QpLA0KIyAgICkgJT4lDQojICAgdW5ncm91cCgpICU+JQ0KIyAgIG11dGF0ZShZZWFyID0gaWZfZWxzZShQZXJpb2QgPT0gMCwgMjAxOCwgWWVhcikpICU+JQ0KIyAgIGZpbHRlcihZZWFyID09IDIwMTgpICU+JQ0KIyAgIHJlbmFtZShGbHUyMDE4ID0gTW9ydGFsaXR5UmF0ZSkNCg0KYGBgDQoNCiMjIyBBZGRpdGlvbmFsIFJJVk0gZGF0YQ0KDQpgYGB7cn0NCmRhdGEucml2bSA8LSByZWFkX3JkcygiLi4vcmVzdWx0cy9yaXZtLlJkcyIpICU+JSByZW5hbWUoUml2bSA9IERlYXRocykNCmBgYA0KDQojIyMgRGF0YSBmb3IgMjAyMCBjb3JvbmEgY3Jpc2lzDQoNCmBgYHtyfQ0KY29scy5jb3JvbmEgPC0NCiAgYygNCiAgICBjb2xzLA0KICAgICJFeHBlY3RlZE1vcnRhbGl0eSIsICJBdmdNb3J0YWxpdHkiLCAiVW5leHBlY3RlZE1vcnRhbGl0eSIsICJFeGNlc3NpdmVNb3J0YWxpdHkiLCAiRmx1MjAxOCINCiAgKQ0KDQpkYXRhLmNvcm9uYSA8LSByZWFkX3JkcygiLi4vcmVzdWx0cy9kYXRhLmNvcm9uYS5SZHMiKSAlPiUgcmVuYW1lKFJlZ2lvID0gUmVnaW9TKSAlPiUgc2VsZWN0KGNvbHMuY29yb25hKSAlPiUNCiAgZnVsbF9qb2luKGRhdGEucml2bSwgYnkgPSBjKCJSZWdpbyIsICJEYXRlIiwgIlBlcmlvZCIpKSAlPiUNCiAgZHJvcF9uYShEYXRlKQ0KDQpkYXRhLmNvcm9uYSAlPiUgZmlsdGVyKFJlZ2lvID09ICJOTCIpICU+JSBhcnJhbmdlKERhdGUpDQpgYGANCg0KIyMjIEdlb2dyYXBoaWNhbCBlbnRpdGllcw0KDQpgYGB7cn0NCmFyZWFzIDwtIEdFVCgiaHR0cHM6Ly9vcGVuZGF0YS5hcmNnaXMuY29tL2RhdGFzZXRzL2UxZjBkZDcwYWJjYjRmY2VhYmJjNDM0MTJlNDNhZDRiXzAuZ2VvanNvbiIpICU+JSBjb250ZW50KGFzID0gInRleHQiKSAlPiUNCiAgcmVhZF9zZigpICU+JQ0KICByZW5hbWUoUmVnaW9TID0gR2VtZWVudGVjb2RlKSAlPiUgDQogIGFycmFuZ2UoR2VtZWVudGVuYWFtKSANCg0Kd3JpdGVfcmRzKGFyZWFzLCAiLi4vcmVzdWx0cy9wbG90cy9hcmVhcy5SZHMiKQ0KYGBgDQoNCiMjIyBDcmVhdGUgYSB0aW1lbGluZSBhbmQgYWRkIHNwbGluZXMgZm9yIHNtb290aCBjaGFydHMNCg0KYGBge3J9DQojIERvIHNvbWUgaW50ZXJwb2xhdGlvbg0KZGF0ZXMgPC0gZGF0YS5jb3JvbmEgJT4lIGRyb3BfbmEoIlBlcmlvZCIsICJEYXRlIikgJT4lIGRpc3RpbmN0KERhdGUpICU+JSBwdWxsKCJEYXRlIikNCmZpZWxkcyA8LSBjKCJNb3J0YWxpdHlSYXRlIiwgIkV4cGVjdGVkTW9ydGFsaXR5IiwgIkF2Z01vcnRhbGl0eSIsICJGbHUyMDE4IiwgIkRlYXRoc1VuZXhwZWN0ZWQiLCAiRGVhdGhzQWJvdmVBdmciLCAiUml2bSIsICJEZWF0aHMiKQ0KZGF5cyA8LSBkYXRhLmZyYW1lKERhdGUgPSBzZXEobWluKGRhdGVzKSwgdG8gPSBtYXgoZGF0ZXMpLCBieSA9ICJkYXlzIikpICU+JQ0KICBjcm9zc2luZyhkYXRhLmNvcm9uYSAlPiUgc2VsZWN0KFJlZ2lvKSAlPiUgZGlzdGluY3QoKSkgJT4lDQogIGNyb3NzaW5nKGZpZWxkcykgJT4lDQogIHNldF9uYW1lcyhjKCJEYXRlIiwgIlJlZ2lvIiwgIlZhcmlhYmxlIikpDQoNCmRhdGEubW9ydCA8LSBkYXRhLmNvcm9uYSAlPiUgDQogIG11dGF0ZSgNCiAgICBEZWF0aHNVbmV4cGVjdGVkID0gVW5leHBlY3RlZE1vcnRhbGl0eSAqIFBvcHVsYXRpb24gLyAxMDAwMDAsDQogICAgRGVhdGhzQWJvdmVBdmcgPSBFeGNlc3NpdmVNb3J0YWxpdHkgKiBQb3B1bGF0aW9uIC8gMTAwMDAwLA0KICApICU+JQ0KICBnYXRoZXIoIlZhcmlhYmxlIiwgIlZhbHVlIiwgZmllbGRzKSAlPiUNCiAgZHJvcF9uYShSZWdpbywgVmFyaWFibGUsIERhdGUpICU+JQ0KICBmdWxsX2pvaW4oZGF5cykgJT4lDQogIGdyb3VwX2J5KFJlZ2lvLCBWYXJpYWJsZSkgJT4lDQogIGZpbHRlcihzdW0oIWlzLm5hKFZhbHVlKSkgPiAwKSAlPiUNCiAgIyBzdW1tYXJpc2UobiA9IG4oKSkgJT4lIGFycmFuZ2UobikNCiAgbXV0YXRlKA0KICAgIEludGVycG9sYXRlZCA9IGFwcHJveChEYXRlLCBWYWx1ZSwgeG91dD1EYXRlKSR5LA0KICAgIEFic29sdXRlID0gaWZfZWxzZShWYXJpYWJsZSA9PSAiTW9ydGFsaXR5UmF0ZSIsIFZhbHVlICogUG9wdWxhdGlvbiAvIDEwMDAwMCwgYXMuZG91YmxlKE5BKSkNCiAgKSAlPiUNCiAgdW5ncm91cCgpICU+JQ0KICBzZWxlY3QoIlJlZ2lvIiwgIkRhdGUiLCAiUGVyaW9kIiwgIlZhcmlhYmxlIiwgIlZhbHVlIiwgIkludGVycG9sYXRlZCIsICJBYnNvbHV0ZSIpDQoNCmRhdGEubW9ydCAlPiUgZmlsdGVyKFJlZ2lvID09ICJOTCIpICU+JSBhcnJhbmdlKERhdGUpDQoNCndyaXRlX3JkcyhkYXRhLm1vcnQsICIuLi9yZXN1bHRzL3Bsb3RzL21vcnRvdmVydGltZS5SZHMiKQ0KYGBgDQoNCiMjIyMgRXhhbXBsZSAxDQoNCmBgYHtyIHB1cmw9Rn0NCnggPC0gZGF0YS5tb3J0ICU+JQ0KICBmaWx0ZXIoVmFyaWFibGUgJWluJSBjKCJNb3J0YWxpdHlSYXRlIiwgIkV4cGVjdGVkTW9ydGFsaXR5IiwgIkF2Z01vcnRhbGl0eSIsICJGbHUyMDE4IikpICU+JQ0KICBmaWx0ZXIoUmVnaW8gPT0gIkdNMDM0NSIpDQoNCnRvb2x0aXAgPC0gKCI8Yj57RGF0ZX08L2I+DQpNb3J0YWxpdHkgcmF0ZToge2Zsb29yKFZhbHVlKX0NCkRlYXRoczoge2Zsb29yKEFic29sdXRlKX0iDQopDQoNCmdncGxvdGx5KHRvb2x0aXAgPSAidGV4dCIsIGdncGxvdCgNCiAgICAgIHgsDQogICAgICBhZXMoDQogICAgICAgIGdyb3VwID0gVmFyaWFibGUsDQogICAgICAgIGNvbG9yID0gVmFyaWFibGUsDQogICAgICAgIHRleHQgPSB0b29sdGlwICU+JSBnbHVlKCkNCiAgICAgICkNCiAgICApICsNCiAgICAgIGdlb21fcG9pbnQoYWVzKHggPSBEYXRlLCB5ID0gVmFsdWUpKSArDQogICAgICBnZW9tX2xpbmUoYWVzKHggPSBEYXRlLCB5ID0gSW50ZXJwb2xhdGVkKSkgKw0KICAgICAgbGFicyh4ID0gIlBlcmlvZCAod2Vla3MpIiAlPiUgZ2x1ZSgpLCB5ID0gIkRlYXRocyBieSAxMDAuMDAwIGluaGFiaXRhbnRzIikgKw0KICAgICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICAgIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkNCikNCmBgYA0KDQojIyMjIEV4YW1wbGUgMg0KDQpgYGB7ciBwdXJsPUZ9DQp4IDwtIGRhdGEubW9ydCAlPiUgDQogIGZpbHRlcihWYXJpYWJsZSAlaW4lIGMoIlJpdm0iLCAiRGVhdGhzQWJvdmVBdmciLCAiRGVhdGhzVW5leHBlY3RlZCIpKSAlPiUNCiAgZmlsdGVyKFJlZ2lvID09ICJOTCIpDQoNCg0KdG9vbHRpcCA8LSAoIjxiPntEYXRlfTwvYj4NCkRlYXRoczoge2Zsb29yKEludGVycG9sYXRlZCl9IikNCg0KZ2dwbG90bHkoZ2dwbG90KA0KICB4LA0KICBhZXMoDQogICAgZ3JvdXAgPSBWYXJpYWJsZSwNCiAgICBjb2xvciA9IFZhcmlhYmxlLA0KICAgIHRleHQgPSAgdG9vbHRpcCAlPiUgZ2x1ZSgpDQogICkNCikgKw0KICBnZW9tX2xpbmUoYWVzKHggPSBEYXRlLCB5ID0gSW50ZXJwb2xhdGVkKSkgKw0KICBnZW9tX3BvaW50KGFlcyh4ID0gRGF0ZSwgeSA9IFZhbHVlKSkgKw0KICBsYWJzKHggPSAiUGVyaW9kICh3ZWVrcykiICU+JSBnbHVlKCksIHkgPSAiQWJzb2x1dGUgZGVhdGhzIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpICsNCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpLA0KDQogIHRvb2x0aXAgPSAidGV4dCINCikNCmBgYA0KDQojIyMgU3BhdGlhbCBkYXRhc2V0DQoNCmBgYHtyfQ0KZGF0YS5zcGF0aWFsX2Fic29sdXRlIDwtIGFyZWFzICU+JSBsZWZ0X2pvaW4oZGF0YS5jb3JvbmEsIGJ5ID0gYygiUmVnaW9TIiA9ICJSZWdpbyIpKSAlPiUgDQogICAgbXV0YXRlKA0KICAgICAgQWN0dWFsTW9ydGFsaXR5ID0gcm91bmQoTW9ydGFsaXR5UmF0ZSAqIFBvcHVsYXRpb24gLyAxMDAwMDApLA0KICAgICAgRXhwZWN0ZWRNb3J0YWxpdHkgPSByb3VuZChFeHBlY3RlZE1vcnRhbGl0eSAqIFBvcHVsYXRpb24gLyAxMDAwMDApLA0KICAgICAgQXZnTW9ydGFsaXR5ID0gcm91bmQoQXZnTW9ydGFsaXR5ICogUG9wdWxhdGlvbiAvIDEwMDAwMCksDQogICAgICBVbmV4cGVjdGVkTW9ydGFsaXR5ID0gcm91bmQoVW5leHBlY3RlZE1vcnRhbGl0eSAqIFBvcHVsYXRpb24gLyAxMDAwMDApLA0KICAgICAgRXhjZXNzaXZlTW9ydGFsaXR5ID0gcm91bmQoRXhjZXNzaXZlTW9ydGFsaXR5ICogUG9wdWxhdGlvbiAvIDEwMDAwMCksDQogICAgKSANCg0Kd3JpdGVfcmRzKGRhdGEuc3BhdGlhbF9hYnNvbHV0ZSwgIi4uL3Jlc3VsdHMvcGxvdHMvc3BhdGlhbF9hYnNvbHV0ZS5SZHMiKQ0KYGBgDQoNCiMjIyMgRXhhbXBsZQ0KDQpgYGB7cn0NCnRtX3NoYXBlKGRhdGEuc3BhdGlhbF9hYnNvbHV0ZSAlPiUgZmlsdGVyKFBlcmlvZCA9PSA0KSkgKw0KICB0bV9wb2x5Z29ucygNCiAgICBjb2wgPSAiTW9ydGFsaXR5UmF0ZSIsDQogICAgaWQgPSAiR2VtZWVudGVuYWFtIiwNCiAgICB0aXRsZSA9ICJNb3J0YWxpdHkgcmF0ZSBieSBtdW5pY2lwYWxpdHkiDQogICkNCmBgYA0KIyMjIFN1bW1hcnkgdGFibGUNCg0KYGBge3J9DQp5ZWFyX2hpZ2hfbW9ydCA8LSBkYXRhLmhpc3RvcmljICU+JSBncm91cF9ieShSZWdpbywgWWVhcikgJT4lIA0KICBzdW1tYXJpc2UoTW9ydGFsaXR5UmF0ZSA9IG1lYW4oTW9ydGFsaXR5UmF0ZSkpICU+JSANCiAgYXJyYW5nZShkZXNjKE1vcnRhbGl0eVJhdGUpKSAlPiUNCiAgc2xpY2UoMSkgJT4lIGFycmFuZ2UoUmVnaW8pICU+JSB1bmdyb3VwKCkgJT4lDQogIHNlbGVjdChZZWFySGlnaGVzdE1vcnQgPSBZZWFyLCBSZWdpbykNCg0KZGF0YS5zdW1tYXJ5IDwtIGRhdGEubW9ydCAlPiUgDQogICAgICBmaWx0ZXIoUGVyaW9kID4gMCAmIFZhcmlhYmxlICVpbiUgYygiRGVhdGhzIiwgIlJpdm0iLCAiRGVhdGhzQWJvdmVBdmciLCAiRGVhdGhzVW5leHBlY3RlZCIpKSAlPiUNCiAgICAgIGdyb3VwX2J5KFJlZ2lvLCBWYXJpYWJsZSkgJT4lDQogICAgICBzdW1tYXJpc2UoVmFsdWUgPSBmbG9vcihzdW0oVmFsdWUsIG5hLnJtID0gVCkpKSAlPiUNCiAgICAgIHNwcmVhZChWYXJpYWJsZSwgVmFsdWUpICU+JQ0KICAgICAgdW5ncm91cCgpICU+JQ0KICAgICAgbGVmdF9qb2luKHllYXJfaGlnaF9tb3J0KQ0KDQoNCndyaXRlX3JkcyhkYXRhLnN1bW1hcnksICIuLi9yZXN1bHRzL3Bsb3RzL3N1bW1hcnkuUmRzIikNCg0KZGF0YS5tb3J0ICU+JSANCiAgZmlsdGVyKFJlZ2lvID09ICJHTTAzNDUiICYgVmFyaWFibGUgJWluJSBjKCJSaXZtIikpICU+JSBhcnJhbmdlKERhdGUpICU+JSANCiAgZ3JvdXBfYnkoUmVnaW8sIFZhcmlhYmxlKSAlPiUgc3VtbWFyaXNlKFZhbHVlID0gc3VtKFZhbHVlLCBuYS5ybSA9IFQpKSAlPiUgc3ByZWFkKFZhcmlhYmxlLCBWYWx1ZSkNCmRhdGEuc3VtbWFyeSAlPiUgZmlsdGVyKFJlZ2lvID09ICJHTTAzNDUiKQ0KYGBgDQoNCg==